package com.jy.rhin.infra.repo.notfication.topic;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jy.common.UIDWorker;
import com.jy.rhin.domain.notification.topic.TopicDao;
import com.jy.rhin.domain.notification.topic.entity.TopicDO;
import com.jy.rhin.infra.repo.notfication.topic.mapper.TopicMapper;
import com.jy.rhin.infra.repo.notfication.topic.mapper.TopicPropertiesMapper;
import com.jy.rhin.infra.repo.notfication.topic.mapper.TopicQueryFilterMapper;
import com.jy.rhin.infra.repo.notfication.topic.mapper.TopicQueryMapper;
import com.jy.rhin.infra.repo.notfication.topic.po.TopicPO;
import com.jy.rhin.infra.repo.notfication.topic.po.TopicPropertiesPO;
import com.jy.rhin.infra.repo.notfication.topic.po.TopicQueryFilterPO;
import com.jy.rhin.infra.repo.notfication.topic.po.TopicQueryPO;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author WeiQ
 * @date 2022/6/28 16:07
 */
@Slf4j
@Component
public class TopicDaoImpl implements TopicDao {
    protected Log mpLog = LogFactory.getLog(getClass());
    @Resource
    TopicMapper topicMapper;
    @Resource
    TopicQueryMapper topicQueryMapper;
    @Resource
    TopicPropertiesMapper topicPropertiesMapper;
    @Resource
    TopicQueryFilterMapper topicQueryFilterMapper;
    @Resource
    UIDWorker uidWorker;

    /**
     * 保存主题记录
     *
     * @param topicDO
     */
    @Override
    public void save(TopicDO topicDO) {
        TopicPO po = new TopicPO(topicDO);
        if (Objects.isNull(po.getId())) {
            //新增
            long id = uidWorker.nextId();
            po.setId(id);
            topicDO.setId(id);
            topicMapper.insert(po);
        } else {
            //更新
            topicMapper.updateById(po);
            //更新需要刷新子表数据，先清空子表关联的数据
            clearTopic(po.getTopicExp());
        }
        //插入子表数据
        List<TopicQueryPO> queryList = new ArrayList<>();
        List<TopicQueryFilterPO> queryFilterList = new ArrayList<>();
        topicDO.getQueryList().forEach(topicQueryVO -> {
            TopicQueryPO topicQueryPo = new TopicQueryPO(topicQueryVO, po.getTopicExp());
            long queryId = uidWorker.nextId();
            topicQueryPo.setId(queryId);
            queryList.add(topicQueryPo);
            topicQueryVO.getFilterList().forEach(topicQueryFilterVO -> {
                TopicQueryFilterPO queryFilterPo = new TopicQueryFilterPO(topicQueryFilterVO, po.getTopicExp(), topicQueryVO.getQueryExp());
                queryFilterPo.setId(uidWorker.nextId());
                queryFilterList.add(queryFilterPo);
            });
        });
        List<TopicPropertiesPO> properties = topicDO.getProperties().stream().map(vo -> {
                    TopicPropertiesPO propertiesPo = new TopicPropertiesPO(vo, topicDO.getTopicExp());
                    propertiesPo.setId(uidWorker.nextId());
                    return propertiesPo;
                })
                .collect(Collectors.toList());
        //批量插入子表数据
        SqlHelper.executeBatch(TopicQueryPO.class, mpLog, queryList, 100, (sqlSession, entity) -> sqlSession.insert(SqlHelper.getSqlStatement(TopicQueryMapper.class, SqlMethod.INSERT_ONE), entity));
        SqlHelper.executeBatch(TopicQueryFilterPO.class, mpLog, queryFilterList, 100, (sqlSession, entity) -> sqlSession.insert(SqlHelper.getSqlStatement(TopicQueryFilterMapper.class, SqlMethod.INSERT_ONE), entity));
        SqlHelper.executeBatch(TopicPropertiesPO.class, mpLog, properties, 100, (sqlSession, entity) -> sqlSession.insert(SqlHelper.getSqlStatement(TopicPropertiesMapper.class, SqlMethod.INSERT_ONE), entity));
    }

    private void clearTopic(String topicExp) {
        topicQueryMapper.removeQueryFilter(topicExp);
        topicQueryMapper.removeQuery(topicExp);
        topicQueryMapper.removeProperties(topicExp);
    }

    /**
     * 根据主题表达式查询主题信息
     *
     * @param topicExp
     * @return
     */
    @Override
    public TopicDO queryByTopicExp(String topicExp) {
        QueryWrapper<TopicPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(TopicPO::getTopicExp, topicExp);
        TopicPO po = topicMapper.selectOne(queryWrapper);
        return Objects.isNull(po) ? null : po.toDO();
    }

}
